import 'dart:convert';
import 'dart:math';
import 'package:crypto/crypto.dart' as crypto;
import 'package:intl/intl.dart';
import 'package:characters/characters.dart';

extension StringUtils on String {
  /// 检查字符串是否为空或只包含空白字符
  bool get isBlank => trim().isEmpty;

  /// 检查字符串是否不为空且不只包含空白字符
  bool get isNotBlank => !isBlank;

  /// 如果字符串为空则返回默认值
  String orDefault(String defaultValue) => isEmpty ? defaultValue : this;

  /// 限制字符串长度，超出部分用省略号代替
  String limit(int maxLength, {String ellipsis = '...'}) {
    if (length <= maxLength) return this;
    return substring(0, maxLength - ellipsis.length) + ellipsis;
  }

  /// 首字母大写
  String get capitalize {
    if (isEmpty) return this;
    return this[0].toUpperCase() + substring(1).toLowerCase();
  }

  /// 移除字符串首尾空格和换行符
  String get trimAll => replaceAll(RegExp(r'^\s+|\s+$'), '');

  /// 检查是否为有效的邮箱格式
  bool get isValidEmail {
    final emailRegex = RegExp(
        r'^[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*@[a-zA-Z0-9-]*[a-zA-Z0-9]+(\.[a-zA-Z0-9-]*[a-zA-Z0-9]+)*(\.[a-zA-Z]{2,})+$');
    return emailRegex.hasMatch(this);
  }

  /// 检查是否为有效的手机号格式（中国）
  bool get isValidChineseMobile {
    final mobileRegex = RegExp(r'^1[3-9]\d{9}$');
    return mobileRegex.hasMatch(this);
  }

  /// 检查是否为有效的URL
  bool get isValidUrl {
    final urlRegex = RegExp(
      r'https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)',
    );
    return urlRegex.hasMatch(this);
  }

  /// 转换为标题格式（每个单词首字母大写）
  String toTitleCase() {
    if (isEmpty) return this;
    return split(' ').map((word) => word.isEmpty ? word : word.capitalize).join(' ');
  }

  /// 隐藏手机号中间4位
  String hideMobile() {
    if (length < 11) return this;
    return replaceRange(3, 7, '****');
  }

  /// 隐藏邮箱用户名部分
  String hideEmail() {
    if (!isValidEmail) return this;
    final parts = split('@');
    final username = parts[0];
    if (username.length <= 2) {
      return '*@$parts[1]';
    }
    return '${username[0]}***${username[username.length - 1]}@$parts[1]}';
  }

  /// 将字符串转换为颜色值
  int toColorValue() {
    String colorStr = toLowerCase().replaceAll('#', '');
    if (colorStr.length == 6) {
      colorStr = 'ff$colorStr'; // 添加透明度
    }
    return int.parse(colorStr, radix: 16);
  }

  /// 检查字符串是否包含中文字符
  bool get containsChinese {
    return RegExp(r'[\u4e00-\u9fa5]').hasMatch(this);
  }

  /// 获取字符串中的数字
  String extractNumbers() {
    return replaceAll(RegExp(r'[^0-9]'), '');
  }

  /// 获取字符串中的中文字符
  String extractChinese() {
    return replaceAll(RegExp(r'[^\u4e00-\u9fa5]'), '');
  }

  /// 检查是否为数字
  bool get isNumeric {
    if (isEmpty) return false;
    return double.tryParse(this) != null;
  }

  /// 检查是否为整数
  bool get isInt {
    if (isEmpty) return false;
    return int.tryParse(this) != null;
  }

  /// 检查是否为有效的身份证号码（中国18位）
  bool get isValidChineseIdCard {
    final idCardRegex = RegExp(r'^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$');
    return idCardRegex.hasMatch(this);
  }

  /// 检查是否为有效的银行卡号（Luhn算法）
  bool get isValidBankCard {
    if (isEmpty || !isNumeric) return false;

    int sum = 0;
    bool isEven = false;

    for (int i = length - 1; i >= 0; i--) {
      int digit = int.parse(this[i]);
      if (isEven) {
        digit *= 2;
        if (digit > 9) digit -= 9;
      }
      sum += digit;
      isEven = !isEven;
    }

    return sum % 10 == 0;
  }

  /// 反转字符串
  String get reverse {
    return split('').reversed.join();
  }

  /// 统计字符串中某个字符出现的次数
  int countOf(String char) {
    if (char.length != 1) return 0;
    return split(char).length - 1;
  }

  /// 检查是否为回文字符串
  bool get isPalindrome {
    final cleanStr = toLowerCase().replaceAll(RegExp(r'[^a-zA-Z0-9]'), '');
    return cleanStr == cleanStr.split('').reversed.join();
  }

  /// 移除字符串中的所有空格
  String get removeAllSpaces => replaceAll(RegExp(r'\s+'), '');

  /// 移除字符串中的HTML标签
  String get removeHtmlTags => replaceAll(RegExp(r'<[^>]*>'), '');

  /// 转换为Base64编码
  String get toBase64 => base64Encode(utf8.encode(this));

  /// 从Base64解码
  String get fromBase64 {
    try {
      return utf8.decode(base64Decode(this));
    } catch (e) {
      return this;
    }
  }

  /// MD5加密
  String get md5 {
    final bytes = utf8.encode(this);
    final digest = crypto.md5.convert(bytes);
    return digest.toString();
  }

  /// SHA256加密
  String get sha256 {
    final bytes = utf8.encode(this);
    final digest = crypto.sha256.convert(bytes);
    return digest.toString();
  }

  /// 隐藏身份证号（保留前6位和后4位）
  String hideIdCard() {
    if (length < 18) return this;
    return replaceRange(6, 14, '********');
  }

  /// 隐藏银行卡号（保留前6位和后4位）
  String hideBankCard() {
    if (length < 16) return this;
    return replaceRange(6, length - 4, '*' * (length - 10));
  }

  /// 格式化手机号（添加空格：138 1234 5678）
  String formatMobile() {
    if (length != 11) return this;
    return '${substring(0, 3)} ${substring(3, 7)} ${substring(7)}';
  }

  /// 格式化银行卡号（每4位添加空格）
  String formatBankCard() {
    final buffer = StringBuffer();
    for (int i = 0; i < length; i++) {
      if (i > 0 && i % 4 == 0) {
        buffer.write(' ');
      }
      buffer.write(this[i]);
    }
    return buffer.toString();
  }

  /// 转换为金额格式（添加千位分隔符）
  String toCurrencyFormat({String separator = ',', int decimalPlaces = 2}) {
    if (!isNumeric) return this;

    final number = double.parse(this);
    final formatter = NumberFormat('#,##0.${'0' * decimalPlaces}');
    return formatter.format(number);
  }

  /// 检查密码强度（包含大小写字母、数字、特殊字符）
  bool get isStrongPassword {
    if (length < 8) return false;

    final hasUpper = RegExp(r'[A-Z]').hasMatch(this);
    final hasLower = RegExp(r'[a-z]').hasMatch(this);
    final hasDigits = RegExp(r'[0-9]').hasMatch(this);
    final hasSpecial = RegExp(r'[!@#$%^&*(),.?":{}|<>]').hasMatch(this);

    return hasUpper && hasLower && hasDigits && hasSpecial;
  }

  /// 生成随机字符串
  static String generateRandomString(int length) {
    const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    final random = Random();
    return List.generate(length, (index) => chars[random.nextInt(chars.length)]).join();
  }

  /// 检查是否为有效的IPv4地址
  bool get isValidIPv4 {
    final ipv4Regex = RegExp(r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$');
    return ipv4Regex.hasMatch(this);
  }

  /// 检查是否为有效的MAC地址
  bool get isValidMacAddress {
    final macRegex = RegExp(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$');
    return macRegex.hasMatch(this);
  }

  /// 转换为首字母缩写
  String get initials {
    if (isBlank) return '';
    return split(' ').where((word) => word.isNotEmpty).map((word) => word[0].toUpperCase()).join();
  }

  /// 检查是否包含Emoji
  bool get containsEmoji {
    final emojiRegex = RegExp(
        r'[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]',
        unicode: true);
    return emojiRegex.hasMatch(this);
  }

  /// 移除Emoji
  String get removeEmojis {
    final emojiRegex = RegExp(
        r'[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]',
        unicode: true);
    return replaceAll(emojiRegex, '');
  }

  /// 转换为Snake Case格式 (helloWorld -> hello_world)
  String get toSnakeCase {
    return replaceAllMapped(RegExp(r'([A-Z])'), (match) => '_${match.group(0)?.toLowerCase()}')
        .replaceAll(RegExp(r'^_'), '');
  }

  /// 转换为Kebab Case格式 (helloWorld -> hello-world)
  String get toKebabCase {
    return replaceAllMapped(RegExp(r'([A-Z])'), (match) => '-${match.group(0)?.toLowerCase()}')
        .replaceAll(RegExp(r'^-'), '');
  }

  /// 转换为Camel Case格式 (hello_world -> helloWorld)
  String get toCamelCase {
    final parts = split(RegExp(r'[-_\s]+'));
    if (parts.isEmpty) return this;

    return parts[0].toLowerCase() + parts.skip(1).map((part) => part.capitalize).join();
  }

  /// 统计字符串长度（考虑中文字符）
  int get unicodeLength {
    return Characters(this).length;
  }

  /// 检查是否为有效的JSON格式
  bool get isValidJson {
    try {
      jsonDecode(this);
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 格式化JSON字符串
  String get formatJson {
    try {
      final dynamic jsonObj = jsonDecode(this);
      return JsonEncoder.withIndent('  ').convert(jsonObj);
    } catch (e) {
      return this;
    }
  }

  /// 检查是否为有效的日期格式
  bool isValidDateFormat([String pattern = 'yyyy-MM-dd']) {
    try {
      final format = DateFormat(pattern);
      format.parseStrict(this);
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 转换为DateTime对象
  DateTime? toDateTime([String pattern = 'yyyy-MM-dd']) {
    try {
      final format = DateFormat(pattern);
      return format.parseStrict(this);
    } catch (e) {
      return null;
    }
  }
}
